<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of Resource
 *
 * @author agama
 */
namespace org\copperforest\oak\authorization;

abstract class Resource
{

    private static $_CLASS_ID;
    private static $_CLASS_NAME;
    private static $_CLASSES;
    private $id;
    private $classnameSHA1; //sha1 del nombre de la clase, para indexar más rapidamente

    function __construct()
    {
        //cuando creo un recurso tengo que encontrar su id en la tabla correspondiente...
        //pero esto no lo se si no comozco la autoridad... Osea solo la autoridad puede crear recursos de un tipo
        // y debiera ser la autoridad la que manejara la cache
        $this->classnameSHA1 = sha1( get_class( $this ), true );
        $this->classId = self::$_CLASS_ID[ $this->classnameSHA1 ];
    }

    function getId()
    {

        $sql = ' SELECT id FROM ct_resouce_' . $this->classId . ' WHERE 1 AND ';

        foreach ( self::$_CLASSES[ $this->classId ][ 'properties' ] as $p )
                $sql.= $p[ 'name' ] . '=' . ( $p[ 'numeric' ] ? $this->$p[ 'name' ] : ct\CT::$PDO->quote( $this->$p[ 'name' ] ) );

        $result = ct\CT::$PDO->query( $sql );
        //tengo que ver que propiedades tengo

        return $id;
    }

    function grantAccess( $rol, $classname )
    {
        //rol_id, resource
        //esto tendría que borrar las cachés de los roles afectados
    }

    function revokeAccess( $rol = null, $classname = null )
    {
        
    }

    function link( Resource $resource )
    { //esto parece que es para conectar por abajo
    }

    function unlink( Resource $resource )
    {
        
    }

    //Aqui puedo definir los métodos para crear recursos
    //tengo que extraer los atributos publicos y tengo que comprobar que exista en la BD
    static private function _scan_folder( $path, &$classes, $len = null )
    {
        if ( $len == null ) $len = strlen( $path );

        $base = str_replace( DIRECTORY_SEPARATOR, '\\',
                substr( $path, $len, -1 ) );


        $files = array_diff( scandir( CF_CLASS_PATH ), array( '.', '..' ) );

        foreach ( $files as $f ) {

            if ( is_dir( $path . $f ) )
                    self::_scan_folder( $path . $f . DIRECTORY_SEPARATOR,
                        $classes, $len );

            else {
                $matches = array( );
                if ( preg_match( '/^(.+).class.php$/', $f, $matches ) ) {

                    if (
                            is_subclass( $base . $matches[ 1 ],
                                    '\org\copperforest\oak\authorization\Resource' ) &&
                            !isset( $classes[ $base . $matches[ 1 ] ] )
                    ) $classes[ $base . $matches[ 1 ] ] = $matches[ 1 ];

                    //tengo que ver que campos gasta
                }
            }
        }
    }

    //TIENE QUE HACER UN DEPLOY COPIANDO LAS PLANTILLAS PARA QUE LAS HEREDEN LAS HIJAS
    static function _deploy()
    {
        //Aqui tb puedo identificar los archivos js y css

        $classes = array( );
        self::_scan_folder( CF_CLASS_PATH, $classes );


        if ( file_exists( CF_OLD_CONFIG_PATH . 'resource.config' ) )
                $old_resources = unserialize( file_get_contents( CF_OLD_CONFIG_PATH . 'resource.config' ) );
        else $old_resources = array( );

        $min_id = 0;
        $nuevo = false;

        foreach ( $classes as $name => $name ) {

            //we keep the old policies id's and reasign the empty indexes
            if ( isset( $old_resources[ $name ] ) ) {
                $id = $old_resources[ $name ][ 'id' ];
            } else {
                $nuevo = true;

                while ( in_array( $min, $old_resources ) )
                    $min_id++;
                $id = $min_id;
                $min_id++;
            }

            self::$_IDS[ $name ] = $id;
            self::$_NAMES[ $id ] = $name;


            $reflex = new ReflectionClass( $name );
            $properties = $reflex->getProperties( ReflectionProperty::IS_PUBLIC & !ReflectionProperty::IS_STATIC );

            $resources[ $name ][ 'props' ] = array( );
            foreach ( $properties as $p ) {
                $resources[ $name ][ 'props' ][ ] = $p->getName();
                //    $resources[ $name ][ 'types' ][ $p->getName() ] = null;
            }

            sort( $resources[ $name ][ 'props' ] );



            if ( !$nuevo && ( $old_resources[ $name ][ 'props' ] != $resources[ $name ][ 'props' ] ) )
                    $name::_deploy();


            $resources[ $name ][ 'id' ] = $id;

            //tengo que comprobar los tipos de datos también se mantienen sino habría que desplegar la tabla de nuevo
            //entonces cada tipo de dato dependerá de la tabla/tablas 

            if ( $nuevo ) {
                //tenque crear 
            }
        }

        //@TODO OJO AQUI TENGO QUE ¿ELIMINAR? Y CREAR TABLAS

        unset( $old_resources, $min_id, $classes );

        //ahora por cada tipo de recurso tengo que crear un tabla, tengo que analizar
        //luego la tabla de los privilegios y luego la de los 
    }

}

?>
